#ifndef __ADXL345_H__
#define __ADXL345_H__

#include "gd32f30x.h"

#define ENABLE_ADXL345      1
#define ADXL345_ADDR        0xA6

#define ADXL345_REG_DEVID                 0x00        /**< device id register */
#define ADXL345_REG_THRESH_TAP            0x1D        /**< thresh tap register */
#define ADXL345_REG_OFSX                  0x1E        /**< x offset register */
#define ADXL345_REG_OFSY                  0x1F        /**< y offset register */
#define ADXL345_REG_OFSZ                  0x20        /**< z offset register */
#define ADXL345_REG_DUR                   0x21        /**< duration time register */
#define ADXL345_REG_LATENT                0x22        /**< latent register */
#define ADXL345_REG_WINDOW                0x23        /**< window register */
#define ADXL345_REG_THRESH_ACT            0x24        /**< act thresh register */
#define ADXL345_REG_THRESH_INACT          0x25        /**< inact thresh register */
#define ADXL345_REG_TIME_INACT            0x26        /**< inact time register */
#define ADXL345_REG_ACT_INACT_CTL         0x27        /**< act inact ctl register */
#define ADXL345_REG_THRESH_FF             0x28        /**< free fall thresh register */
#define ADXL345_REG_TIME_FF               0x29        /**< free fall time register */
#define ADXL345_REG_TAP_AXES              0x2A        /**< tap axes register */
#define ADXL345_REG_ACT_TAP_STATUS        0x2B        /**< act tap status register */
#define ADXL345_REG_BW_RATE               0x2C        /**< bandwidth rate register */
#define ADXL345_REG_POWER_CTL             0x2D        /**< power control register */
#define ADXL345_REG_INT_ENABLE            0x2E        /**< interrupt enable register */
#define ADXL345_REG_INT_MAP               0x2F        /**< interrupt map register */
#define ADXL345_REG_INT_SOURCE            0x30        /**< interrupt source register */
#define ADXL345_REG_DATA_FORMAT           0x31        /**< data format register */
#define ADXL345_REG_DATAX0                0x32        /**< data X0 register */
#define ADXL345_REG_DATAX1                0x33        /**< data X1 register */
#define ADXL345_REG_DATAY0                0x34        /**< data Y0 register */
#define ADXL345_REG_DATAY1                0x35        /**< data Y1 register */
#define ADXL345_REG_DATAZ0                0x36        /**< data Z0 register */
#define ADXL345_REG_DATAZ1                0x37        /**< data Z1 register */
#define ADXL345_REG_FIFO_CTL              0x38        /**< fifo control register */
#define ADXL345_REG_FIFO_STATUS           0x39        /**< fifo status register */

typedef enum
{
    ADXL345_BOOL_FALSE = 0x00,        /**< false */
    ADXL345_BOOL_TRUE  = 0x01,        /**< true */
} adxl345_bool_t;


typedef enum
{
    ADXL345_INTERRUPT_ACTIVE_LEVEL_HIGH = 0x00,        /**< interrupt active level high */
    ADXL345_INTERRUPT_ACTIVE_LEVEL_LOW  = 0x01,        /**< interrupt active level low */
} adxl345_interrupt_active_level_t;

/**
 * @brief adxl345 sleep frequency enumeration definition
 */
typedef enum
{
    ADXL345_SLEEP_FREQUENCY_8HZ = 0x00,        /**< sleep 8Hz */
    ADXL345_SLEEP_FREQUENCY_4HZ = 0x01,        /**< sleep 4Hz */
    ADXL345_SLEEP_FREQUENCY_2HZ = 0x02,        /**< sleep 2Hz */
    ADXL345_SLEEP_FREQUENCY_1HZ = 0x03,        /**< sleep 1Hz*/
} adxl345_sleep_frequency_t;

/**
 * @brief adxl345 mode enumeration definition
 */
typedef enum
{
    ADXL345_MODE_BYPASS  = 0x00,        /**< bypass mode */
    ADXL345_MODE_FIFO    = 0x01,        /**< fifo mode */
    ADXL345_MODE_STREAM  = 0x02,        /**< stream mode */
    ADXL345_MODE_TRIGGER = 0x03,        /**< trigger mode */
} adxl345_mode_t;

/**
 * @brief adxl345 interrupt pin enumeration definition
 */
typedef enum
{
    ADXL345_INTERRUPT_PIN1 = 0x00,        /**< interrupt pin 1 */
    ADXL345_INTERRUPT_PIN2 = 0x01,        /**< interrupt pin 2 */
} adxl345_interrupt_pin_t;

typedef enum
{
    ADXL345_TAP_AXIS_X = 0x02,        /**< x axis tap */
    ADXL345_TAP_AXIS_Y = 0x01,        /**< y axis tap */
    ADXL345_TAP_AXIS_Z = 0x00,        /**< z axis tap */
} adxl345_tap_axis_t;

typedef enum
{
    ADXL345_INTERRUPT_DATA_READY = 0x07,        /**< data ready */
    ADXL345_INTERRUPT_SINGLE_TAP = 0x06,        /**< single tap */
    ADXL345_INTERRUPT_DOUBLE_TAP = 0x05,        /**< double tap */
    ADXL345_INTERRUPT_ACTIVITY   = 0x04,        /**< activity */
    ADXL345_INTERRUPT_INACTIVITY = 0x03,        /**< inactivity */
    ADXL345_INTERRUPT_FREE_FALL  = 0x02,        /**< free fall */
    ADXL345_INTERRUPT_WATERMARK  = 0x01,        /**< watermark */
    ADXL345_INTERRUPT_OVERRUN    = 0x00,        /**< overrun */
} adxl345_interrupt_t;

typedef enum
{
    ADXL345_ACTION_X   = 0x06,        /**< x axis action */
    ADXL345_ACTION_Y   = 0x05,        /**< y axis action */
    ADXL345_ACTION_Z   = 0x04,        /**< z axis action */
    ADXL345_INACTION_X = 0x02,        /**< x axis inaction */
    ADXL345_INACTION_Y = 0x01,        /**< y axis inaction */
    ADXL345_INACTION_Z = 0x00,        /**< z axis inaction */
} adxl345_action_inaction_t;

typedef enum
{
    ADXL345_COUPLED_DC = 0x00,        /**< DC coupled */
    ADXL345_COUPLED_AC = 0x01,        /**< AC coupled */
} adxl345_coupled_t;

typedef enum
{
    ADXL345_JUSTIFY_RIGHT = 0x00,        /**< right justify */
    ADXL345_JUSTIFY_LEFT  = 0x01,        /**< left justify */
} adxl345_justify_t;

typedef enum
{
    ADXL345_RATE_0P1            = 0x00,        /**< 0.1Hz */
    ADXL345_RATE_0P2            = 0x01,        /**< 0.2Hz */
    ADXL345_RATE_0P39           = 0x02,        /**< 0.39Hz */
    ADXL345_RATE_0P78           = 0x03,        /**< 0.78Hz */
    ADXL345_RATE_1P56           = 0x04,        /**< 1.56Hz */
    ADXL345_RATE_3P13           = 0x05,        /**< 3.13Hz */
    ADXL345_RATE_6P25           = 0x06,        /**< 6.25Hz */
    ADXL345_RATE_12P5           = 0x07,        /**< 12.5Hz */
    ADXL345_RATE_25             = 0x08,        /**< 25Hz */
    ADXL345_RATE_50             = 0x09,        /**< 50Hz */
    ADXL345_RATE_100            = 0x0A,        /**< 100Hz */
    ADXL345_RATE_200            = 0x0B,        /**< 200Hz */
    ADXL345_RATE_400            = 0x0C,        /**< 400Hz */
    ADXL345_RATE_800            = 0x0D,        /**< 800Hz */
    ADXL345_RATE_1600           = 0x0E,        /**< 1600Hz */
    ADXL345_RATE_3200           = 0x0F,        /**< 3200Hz */
    ADXL345_LOW_POWER_RATE_12P5 = 0x17,        /**< low power 12.5Hz */
    ADXL345_LOW_POWER_RATE_25   = 0x18,        /**< low power 25Hz */
    ADXL345_LOW_POWER_RATE_50   = 0x19,        /**< low power 50Hz */
    ADXL345_LOW_POWER_RATE_100  = 0x1A,        /**< low power 100Hz */
    ADXL345_LOW_POWER_RATE_200  = 0x1B,        /**< low power 200Hz */
    ADXL345_LOW_POWER_RATE_400  = 0x1C,        /**< low power 400Hz */
} adxl345_rate_t;

typedef enum
{
    ADXL345_RANGE_2G  = 0x00,        /**< ±2G */
    ADXL345_RANGE_4G  = 0x01,        /**< ±4G */
    ADXL345_RANGE_8G  = 0x02,        /**< ±8G */
    ADXL345_RANGE_16G = 0x03,        /**< ±16G */
} adxl345_range_t;

void adxl345_xyz_read_init();
void adxl345_active_init();
void adxl345_tap_init();
#endif